package com.ds.iot.comet;

import com.ds.cluster.ServerNode;
import com.ds.common.JDSException;
import com.ds.context.JDSCometContext;
import com.ds.context.JDSContext;
import com.ds.engine.ConnectInfo;
import com.ds.engine.ConnectionHandle;
import com.ds.engine.JDSSessionHandle;
import com.ds.iot.Device;
import com.ds.iot.HomeConstants;
import com.ds.iot.ct.CtIotFactory;
import com.ds.msg.Msg;
import com.ds.org.Person;
import com.ds.org.PersonNotFoundException;
import com.ds.server.JDSClientService;
import com.ds.server.JDSServer;
import com.ds.server.OrgManagerFactory;
import com.ds.server.comet.AbstractCometHandle;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Set;

public class GWReConnectCometHandle extends AbstractCometHandle {
    private String ieee;

    public GWReConnectCometHandle(JDSClientService client, JDSSessionHandle sessionHandle, String systemCode) throws JDSException {
        super(client, sessionHandle, systemCode);

    }

    public void receive(String receiveStr) throws JDSException {
        logger.info("receive user:[" + getConnectInfo().getLoginName() + "] ");
        logger.info(receiveStr);
    }

    public boolean send(String msgString) throws JDSException {
        logger.info("sendCommand[" + ieee + "]:" + msgString);
        return super.send(msgString);
    }

    class ClearSession implements Runnable {
        private ConnectionHandle sessionHandle;
        private ConnectInfo connectInfo;
        private String systemCode;

        ClearSession(ConnectInfo connectInfo, ConnectionHandle handle, String systemCode) {
            this.sessionHandle = handle;
            this.connectInfo = connectInfo;
            this.systemCode = systemCode;
        }

        public void run() {
            try {
                Set<JDSSessionHandle> sessionHandleList = JDSServer.getInstance().getSessionHandleList(connectInfo);
                for (JDSSessionHandle handle : sessionHandleList) {
                    if (!handle.toString().equals(sessionHandle.toString())) {
                        JDSClientService client = JDSServer.getInstance().getJDSClientService(handle, JDSServer.getInstance().getAdminClient().getConfigCode());
                        if (client != null && client.getConnectInfo() != null) {
                            client.getConnectionHandle().disconnect();
                        }
                    }

                }
            } catch (JDSException e) {
                e.printStackTrace();
            }

        }

    }


    public void connect(JDSContext context) throws JDSException {
        if (context instanceof JDSCometContext) {
            JDSCometContext cometContext = (JDSCometContext) context;
            this.request = (HttpServletRequest) cometContext.getHttpRequest();
            this.response = (HttpServletResponse) cometContext.getHttpResponse();
        } else {
            throw new JDSException("用户未登录！", JDSException.PROCESSDEFINITIONERROR);
        }

        if (this.connectInfo == null) {
            connectInfo = this.getClient().getConnectInfo();
        }

        if (this.connectInfo == null) {
            try {
                connectInfo = JDSServer.getInstance().getConnectInfo(this.getClient().getSessionHandle());

            } catch (JDSException e) {
                logger.error(e);
            }
            if (this.connectInfo == null) {
                String ieee = (String) context.getParams("ieee");
                if (ieee != null) {
                    Device device = CtIotFactory.getCtIotService().getDeviceByIeee(ieee);
                    try {
                        Person person = OrgManagerFactory.getOrgManager().getPersonByAccount(device.getBindingaccount());
                        connectInfo = new ConnectInfo(person.getID(), person.getAccount(), person.getPassword());
                    } catch (PersonNotFoundException e1) {
                        logger.error(e1);
                    }
                }
            }

            this.getClient().connect(connectInfo);
        }


        if (this.connectInfo == null) {
            throw new JDSException("用户未登录！", JDSException.PROCESSDEFINITIONERROR);
        }


        int index = -1;
        Set<JDSSessionHandle> sessionHandleList = JDSServer.getInstance().getSessionHandleList(connectInfo);
        for (JDSSessionHandle handle : sessionHandleList) {
            Long loginTime = JDSServer.getInstance().getConnectTimeCache().get(handle.toString());
            if (loginTime != null && (System.currentTimeMillis() - loginTime) < 31 * 1000) {
                index = 0;
            }
        }

        if (index == -1) {
            send("sessiontimeout,  place login frist!");
            return;
        }


        client.connect(connectInfo);
        this.ieee = (String) context.getParams("ieee");
        sessionMapUser.put(context.getSessionId(), connectInfo.getUserID());

        logger.info("user:" + connectInfo.getLoginName() + "[" + context.getSessionId() + "] cometLogin success");
        int k = 0;
        while (isClose) {
            JDSClientService client = this.getClient();
            ConnectInfo connectionInfo = client.getConnectInfo();
            if (client != null && connectionInfo != null) {
                Long lastLoginTime = checkTime.get(context.getSessionId());
                Long lastCommandTime = checkHeart.get("Herat" + context.getSessionId() + "");

                if (lastCommandTime == null) {
                    lastCommandTime = System.currentTimeMillis();
                    checkHeart.put("Herat" + context.getSessionId() + "", lastCommandTime);

                }

                Long lastHeartTime = checkCommandHeart.get(context.getSessionId());

                if (lastLoginTime == null) {
                    lastLoginTime = System.currentTimeMillis();
                    checkTime.put(context.getSessionId(), lastLoginTime);
                }

//               //修改session更新时间
//                if (sessionMapUser.get(this.client.getContext().getSessionId()) != null) {
//                    //         if (System.currentTimeMillis() - lastLoginTime > 30 * 1000 && sessionMapUser.get(context.getSessionId()) != null) {
//                    checkTime.put(context.getSessionId(), System.currentTimeMillis());
//                    client.connect(connectInfo);
//                }

                if (lastHeartTime == null) {
                    lastHeartTime = System.currentTimeMillis();
                    checkCommandHeart.put(context.getSessionId(), lastHeartTime);
                }

                if (k >= 6) {
                    this.reConnect();

                    String sessionid = this.client.getContext().getSessionId();

                    String commandUrl = this.getUrl(connectInfo.getLoginName());

                    String command = "{\"command\":\"CommandReConnect\",\"url\":\"" + commandUrl + "\",\"sessionid\":\"" + sessionid + "\"}";
                    //   logger.info(command);
                    sessionMapUser.put(sessionid, connectInfo.getUserID());
                    send(command);
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        isClose = false;
                        send(e.getMessage());

                    }

                    //  isClose = false;
                    // this.disconnect();

                } else {
                    send(HEARTKEY);
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        isClose = false;
                        send(e.getMessage());

                    }
                    k = k + 1;

                }

            } else {
                isClose = false;

                send("sessionId is  null,  place login frist!");

                disconnect();
            }
        }


    }

    public String getUrl(String deviceId) throws JDSException {
        String commandUrl = JDSServer.getInstance().getCurrServerBean().getUrl();

        Device device = CtIotFactory.getCtIotService().getDeviceById(deviceId);
        ServerNode serverBean = JDSServer.getClusterClient().getServerNodeById(device.getSubsyscode());

        if (serverBean == null) {
            serverBean = JDSServer.getClusterClient().getServerNodeById(device.getFactory());
            device.setSubsyscode(device.getFactory());
        }
        if (serverBean == null) {
            serverBean = JDSServer.getClusterClient().getServerNodeById("jds");
            device.setSubsyscode(device.getFactory());
        }

//        if (serverBean != null && serverBean.getCommandserver() != null && !serverBean.getCommandserver().equals("")) {
//            commandUrl = serverBean.getCommandserver() + HomeConstants.SYSTEM_COMMANDSERVERURL;
//        }

        if (!commandUrl.endsWith(HomeConstants.SYSTEM_COMMANDSERVERURL)) {
            commandUrl = commandUrl + HomeConstants.SYSTEM_COMMANDSERVERURL;
        }

        return commandUrl;
    }


    public void disconnect(String sessionId) throws JDSException {

        //  sessionMapUser.remove(sessionId);

        try {

            Set<JDSSessionHandle> handles = JDSServer.getInstance().getSessionHandleList(this.getConnectInfo());

            for (JDSSessionHandle handel : handles) {
                JDSServer.getInstance().disconnect(handel);
                sessionMapUser.remove(handel.getSessionID());
            }

        } catch (Exception localException) {
            localException.printStackTrace();
        }

        super.disconnect();
    }

    @Override
    public boolean repeatMsg(Msg msg, JDSSessionHandle handle) throws JDSException {
        return false;
    }
}
